package com.googlecode.delivery.core.impl;

import java.io.File;
import java.io.IOException;
import java.util.zip.ZipFile;

import org.apache.log4j.Logger;

import com.googlecode.delivery.DeliveryException;
import com.googlecode.delivery.model.DeploymentUnit;
import com.googlecode.delivery.model.Environment;

/**
 * 
 * 
 * @author kst
 */
public class DeploymentUnitFactory {
	private static final Logger LOGGER = Logger
			.getLogger(DeploymentUnitFactory.class);

	public static String[] SUPPORTED_SUFFIXES = new String[] { "ear", "war",
			"jar" };

	/** Factory */
	private DeploymentUnitFactory() {
	}

	/**
	 * Loads and validates the Deployment Unit.
	 * 
	 * @throws DeliveryException
	 */
	public static DeploymentUnit create(File zipFile) throws DeliveryException {
		if (!zipFile.exists()) {
			throw new DeliveryException("input file does not exist :"
					+ zipFile.getAbsolutePath());
		}
		String name = zipFile.getName().substring(0,
				zipFile.getName().lastIndexOf('.'));
		String type = zipFile.getName().substring(
				zipFile.getName().lastIndexOf('.') + 1);
		DeploymentUnit du = new DeploymentUnit(name, type);
		try {
			ZipFile artefact = new ZipFile(zipFile);
			File tmpFile = File.createTempFile(zipFile.getName(), null);
			File explodedDir = new File(tmpFile.getAbsolutePath().substring(0,
					tmpFile.getAbsolutePath().lastIndexOf('.')));
			explodedDir.mkdir();

			LOGGER.info("Extracting " + artefact.getName() + " to "
					+ explodedDir.getAbsolutePath());
			FileUtils.extract(artefact, explodedDir);

			LOGGER.info("[OK] Artifact exploded.");
			du.setExplodedDir(explodedDir);
			Environment env = EnvironmentHelper.create(du.getEnvFile());
			du.setEnvironment(env);
			return du;
		} catch (IOException ioe) {
			throw new DeliveryException(
					"Error caught while loading artefact : "
							+ zipFile.getAbsolutePath(), ioe);
		}
	}

	

	/**
	 * Checks if given artefact is configurable.
	 * 
	 * @param artefact
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static boolean isConfigurable(ZipFile artefact)
			throws DeliveryException {
		boolean isSupported = false;
		for (int i = 0; i < SUPPORTED_SUFFIXES.length; i++) {
			isSupported |= artefact.getName().endsWith(
					"." + SUPPORTED_SUFFIXES[i]);
		}
		if (!isSupported) {
			throw new DeliveryException("Artifact " + artefact
					+ " is not configurable.");
		}
		boolean isConfigurable = false;
		boolean hasDeliveryDir = false;
		boolean hasEnvironment = false;
		for (java.util.Enumeration e = artefact.entries(); e.hasMoreElements()
				&& !isConfigurable;) {
			java.util.zip.ZipEntry entry = (java.util.zip.ZipEntry) e
					.nextElement();
			hasDeliveryDir |= (entry.getName().indexOf(
					DeploymentUnit.DELIVERY_ROOT_DIR) == 0);
			hasEnvironment |= (entry.getName().indexOf(
					DeploymentUnit.DELIVERY_ROOT_DIR
							+ DeploymentUnit.ENVIRONMENT_FILE_NAME) == 0);
			isConfigurable = hasDeliveryDir && hasEnvironment;
		}
		return isConfigurable;
	}

}
